
//http://www.yanhuangxueyuan.com/
//下面的代码大部分是从上面这个网站上扒下来,然后自己做了一下简单的封装



// 使用时，只需调用此函数并传递所需的背景颜色和点点颜色。
// 例如: customizeBackgroundAndDotColor('rgb(255, 255, 255)', '0.0,0.0,0.0,1.0');
//第一个参数是背景颜色,直接给rgb值或者16进制的颜色值就行,
//第二个参数是点点颜色,这行代码是设置点点的颜色，前三位是颜色，第四位是透明度(0.0=完全透明,1.0等于不透明)，前面的颜色值范围是0.0到1.0(需要把RGB转换一下)
function customizeBackgroundAndDotColor(backgroundColor, dotColor) {
    
    (function () {
        const oldElement = document.querySelector('div[fgc-gui-bgname="背景图1"] > div');
        if (oldElement) {
            const newCanvas = document.createElement('canvas');
            newCanvas.id = 'webgl';
            newCanvas.style.height = '100%';
            newCanvas.style.backgroundColor = backgroundColor;
            newCanvas.style.width = '100%';
            newCanvas.width = 1627;
            newCanvas.height = 1929;
            oldElement.parentNode.replaceChild(newCanvas, oldElement);
        } else {
           // console.log("The specified div was not found.");
        }
    })();

    injectVertexShader();

    (function () {
        var existingScript = document.getElementById('fragmentShader');
        if (existingScript) {
            existingScript.remove();
        }

        var scriptElem = document.createElement('script');
        scriptElem.id = 'fragmentShader';
        scriptElem.type = 'x-shader/x-fragment';
        scriptElem.textContent = `
            void main() {
                if (length(gl_PointCoord - vec2(0.5, 0.5)) > 0.49) discard;
                gl_FragColor = vec4(${dotColor}); 
            }
        `;
        document.body.appendChild(scriptElem);
    })();

    initParticleAnimation();
}


function injectVertexShader() {
	if (document.getElementById('vertexShader')) {
		return;
	}
	var scriptElem = document.createElement('script');
	scriptElem.id = 'vertexShader';
	scriptElem.type = 'x-shader/x-vertex';
	scriptElem.textContent = `
    attribute vec4 position;
    attribute float scale;
    uniform mat4 modelViewMatrix;
    uniform mat4 projectionMatrix;
    void main() {
        vec4 mvPosition = modelViewMatrix * position;
        gl_PointSize = scale*1.0 * ( 200.0 / - mvPosition.z );
        gl_Position = projectionMatrix * mvPosition;
    }
    `;
	document.body.appendChild(scriptElem);
}


function initParticleAnimation() {
	var webgl = document.getElementById("webgl")
	webgl.style.width = window.innerWidth + "px";
	webgl.style.height = window.innerHeight + "px";

	var width = window.innerWidth;
	var height = window.innerHeight;

	var mid = width / 2 - 160 / 2; //中间位置
	// 两侧分别平移150

	// webgl.width = window.innerWidth;
	// webgl.height = window.innerHeight;

	(function () {
		window.onload = function () {
			function throttle(fun, delay, time) {
				var timeout,
					startTime = new Date();
				return function () {
					var context = this,
						args = arguments,
						curTime = new Date();
					clearTimeout(timeout);
					if (curTime - startTime >= time) {
						fun.apply(context, args);
						startTime = curTime;
					} else {
						timeout = setTimeout(fun, delay);
					}
				};
			};
			window.onscroll = throttle(watchscroll, 1, 500);

			function watchscroll() {
				var bodyScrollHeight = document.documentElement.scrollTop || document.body.scrollTop; // body滚动高度
				var windowHeight = window.innerHeight;
				var imgs = document.getElementsByClassName('lazyloadimg');
				if (imgs && imgs.length > 0) {
					for (var i = 0; i < imgs.length; i++) {
						var imgHeight = imgs[i].offsetTop;
						if (imgHeight < windowHeight + bodyScrollHeight) {
							imgs[i].src = imgs[i].getAttribute('data-src');
							imgs[i].className = imgs[i].className.replace('lazyloadimg', '')
						}
					}
				}
			}
		}
	})()

	var canvas = document.getElementById('webgl');
	// var canvas = document.createElement('canvas');
	// div.appendChild(canvas)
	canvas.width = window.innerWidth;
	canvas.height = window.innerHeight;

	var gl = canvas.getContext('webgl');

	var vertexShaderSource = document.getElementById('vertexShader').innerText;

	var fragShaderSource = document.getElementById('fragmentShader').innerText;

	var program = initShader(gl, vertexShaderSource, fragShaderSource);

	var aposLocation = gl.getAttribLocation(program, 'position');
	var scale = gl.getAttribLocation(program, 'scale');

	var modelViewMatrixLoc = gl.getUniformLocation(program, 'modelViewMatrix');
	var projectionMatrixLoc = gl.getUniformLocation(program, 'projectionMatrix');




	var SEPARATION = 100,
		AMOUNTX = 50,
		AMOUNTY = 50;
	var numParticles = AMOUNTX * AMOUNTY;

	var positions = new Float32Array(numParticles * 3);
	var scales = new Float32Array(numParticles);

	var i = 0,
		j = 0;

	for (var ix = 0; ix < AMOUNTX; ix++) {

		for (var iy = 0; iy < AMOUNTY; iy++) {

			positions[i] = ix * SEPARATION - ((AMOUNTX * SEPARATION) / 2); // x
			positions[i + 1] = 0; // y
			positions[i + 2] = iy * SEPARATION - ((AMOUNTY * SEPARATION) / 2); // z
			scales[j] = 1;
			i += 3;
			j++;

		}

	}

	var colorBuffer = gl.createBuffer();
	gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
	gl.bufferData(gl.ARRAY_BUFFER, scales, gl.STATIC_DRAW);
	gl.vertexAttribPointer(scale, 1, gl.FLOAT, false, 0, 0);
	gl.enableVertexAttribArray(scale);

	var buffer = gl.createBuffer();
	gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
	gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW);
	gl.vertexAttribPointer(aposLocation, 3, gl.FLOAT, false, 0, 0);
	gl.enableVertexAttribArray(aposLocation);

	gl.enable(gl.DEPTH_TEST);

	var width = window.innerWidth; //
	var height = window.innerHeight; //
	var camera = new THREE.PerspectiveCamera(60, width / height, 1, 10000);
	camera.position.set(200, 300, 200); //

	camera.position.set(944, 206, -262);
	camera.lookAt(new THREE.Vector3(0, 0, 0)); //()
	camera.updateProjectionMatrix()
	camera.updateMatrixWorld(true)

	var width = window.innerWidth; //
	var height = window.innerHeight; //
	var mat4 = new THREE.Matrix4();
	mat4.copy(camera.projectionMatrix)

	var mxArr = new Float32Array(mat4.elements);

	gl.uniformMatrix4fv(projectionMatrixLoc, false, mxArr);

	var mat4y = new THREE.Matrix4();

	mat4y.copy(camera.matrixWorldInverse);

	console.log(camera.matrixWorldInverse);
	var myArr = new Float32Array(mat4y.elements);

	gl.uniformMatrix4fv(modelViewMatrixLoc, false, myArr);


	var count = 0;
	var mouseX = 0,
		mouseY = 0;

	var windowHalfX = window.innerWidth / 2;
	var windowHalfY = window.innerHeight / 2;

	function draw() {
		camera.position.x += (mouseX - camera.position.x) * 0.01;

		camera.updateMatrixWorld(true)
		mat4y.copy(camera.matrixWorldInverse);

		var myArr = new Float32Array(mat4y.elements);
		gl.uniformMatrix4fv(modelViewMatrixLoc, false, myArr);

		var i = 0,
			j = 0;

		for (var ix = 0; ix < AMOUNTX; ix++) {
			for (var iy = 0; iy < AMOUNTY; iy++) {
				positions[i + 1] = (Math.sin((ix + count) * 0.3) * 50) +
					(Math.sin((iy + count) * 0.5) * 50);
				scales[j] = (Math.sin((ix + count) * 0.3) + 1.3) * 8 +
					(Math.sin((iy + count) * 0.5) + 1.3) * 8;
				i += 3;
				j++;
			}
		}
		count += 0.1;

		gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
		gl.bufferData(gl.ARRAY_BUFFER, scales, gl.STATIC_DRAW);

		gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
		gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW);

		requestAnimationFrame(draw);

		gl.drawArrays(gl.POINTS, 0, 2500);
	}
	draw();



	function initShader(gl, vertexShaderSource, fragmentShaderSource) {
		var vertexShader = gl.createShader(gl.VERTEX_SHADER);
		var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
		gl.shaderSource(vertexShader, vertexShaderSource);
		gl.shaderSource(fragmentShader, fragmentShaderSource);
		gl.compileShader(vertexShader);
		gl.compileShader(fragmentShader);
		var program = gl.createProgram();
		gl.attachShader(program, vertexShader);
		gl.attachShader(program, fragmentShader);
		gl.linkProgram(program);
		gl.useProgram(program);
		return program;
	}

	document.addEventListener('mousemove', onDocumentMouseMove, false);
	document.addEventListener('touchstart', onDocumentTouchStart, false);
	document.addEventListener('touchmove', onDocumentTouchMove, false);

	function onDocumentMouseMove(event) {

		mouseX = event.clientX - windowHalfX;
		mouseY = event.clientY - windowHalfY;

	}

	function onDocumentTouchStart(event) {

		if (event.touches.length === 1) {

			event.preventDefault();

			mouseX = event.touches[0].pageX - windowHalfX;
			mouseY = event.touches[0].pageY - windowHalfY;

		}

	}

	function onDocumentTouchMove(event) {

		if (event.touches.length === 1) {

			event.preventDefault();

			mouseX = event.touches[0].pageX - windowHalfX;
			mouseY = event.touches[0].pageY - windowHalfY;

		}

	}

	var width = window.innerWidth;
	var height = window.innerHeight;

	var mid = width / 2 - 160 / 2; //中间位置

	window.onresize = function () {

		canvas.width = window.innerWidth;
		canvas.height = window.innerHeight;
		gl.viewport(0, 0, window.innerWidth, window.innerHeight);
		camera.aspect = window.innerWidth / window.innerHeight;
		camera.updateProjectionMatrix();
		mat4.copy(camera.projectionMatrix)
		var mxArr = new Float32Array(mat4.elements);
		gl.uniformMatrix4fv(projectionMatrixLoc, false, mxArr);

		var width = window.innerWidth;
		var height = window.innerHeight;

		var mid = width / 2 - 160 / 2; //中间位置
		// 两侧分别平移150

		canvas.style.width = window.innerWidth + "px";
		canvas.style.height = window.innerHeight + "px";
	};
}